home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
551-575
/
disk_553
/
24bittools
/
pro2iff
/
readilbm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
7KB
|
234 lines
#include <functions.h>
#include "iff.h"
extern void *IntuitionBase,*GfxBase,*DiskfontBase;
/* READILBM.C : based on NewZAP's READILBM.C
(c) 1986,1990,1991 Dallas J. Hodgson
Loads bitmaps into MEMF_PUBLIC
*/
LoadMode Mode;
unsigned char *pdiskptr;
/************************************************************************
* *
* Routine name(s) : ReadILBM() *
* Author : D. John Hodgson *
* Environment : Aztec "C", default *
* *
* ReadILBM attempts to read an IFF file into an user-supplied *
* bitmap. Returns FALSE if successful. Brushes supported. *
* *
* OPTIONS : Filespec reflects user-supplied pointer to IFF file in *
* RAM if mode argument is non-zero. Otherwise, disk. *
* *
* LIMITATIONS : Bare-bones ILBM; no CATS/LISTS/PROPS. *
* All other graphics (compressed or not) supported. *
************************************************************************/
BPTR OpenNEW(unsigned char *name,long accessMode)
{
if (Mode==DISK_MODE) return(Open((char *)name,accessMode));
pdiskptr=name; /* initialize pseudo-disk RAM ptr */
return((BPTR)pdiskptr);
}
long ReadNEW(BPTR file,char *buffer,long length)
{
if (Mode==DISK_MODE) return(Read(file,buffer,length));
movmem(pdiskptr,buffer,(unsigned int)length);
pdiskptr+=length;
return(length);
}
long SeekNEW(BPTR file,long position,long tmode)
{
if (Mode==DISK_MODE) return(Seek(file,position,tmode));
/* Note : RAM seek only supports one mode : OFFSET_CURRENT! */
if (tmode!=OFFSET_CURRENT) return(BAD_MODE);
pdiskptr+=position;
return((long)pdiskptr-position); /* Seek() returns previous position! */
}
void CloseNEW(BPTR file)
{
if (Mode==DISK_MODE) Close(file);
}
ReadILBM(char *fspec,LoadMode mode,struct PicMap *picmap)
{
BPTR fp;
Chunk header;
BitMapHeader bmhd;
unsigned char *tmp,*bufstart,*sourcebuf;
UWORD i,color;
long id;
Mode=mode;
memset(picmap,0,sizeof(*picmap));
if (!(fp=OpenNEW((unsigned char *)fspec,MODE_OLDFILE))) return(DISK_ERR);
SafeRead(fp,&header,(long)sizeof(header));
if (header.ckID!=ID_FORM) { CloseNEW(fp); return(IFF_ERR); }
SafeRead(fp,&id,(long)sizeof(id));
if (id!=ID_ILBM) { CloseNEW(fp); return(IFF_ERR); }
for (;;) {
SafeRead(fp,&header,(long)sizeof(header));
if (header.ckID==ID_BODY) break;
switch(header.ckID) {
case ID_BMHD: SafeRead(fp,&bmhd,(long)sizeof(bmhd));
/* force WORD boundary for all pics */
bmhd.w=(bmhd.w + 0xf) & 0xfff0;
break;
case ID_CMAP: tmp=picmap->palette;
SafeRead(fp,tmp,(long)header.ckSize);
for (i=0;i<header.ckSize/3;i++) {
color = (*tmp++ & 0xf0) << 4;
color |= (*tmp++ & 0xf0);
color |= *tmp++ >> 4;
picmap->colormap[i]=color;
}
break;
case ID_CAMG: SafeRead(fp,&picmap->ViewModes,(long)header.ckSize);
break;
default: SeekNEW(fp,ROUNDODDUP(header.ckSize),OFFSET_CURRENT);
}
}
/* make some forced assumptions if CAMG chunk unavailable */
if (!picmap->ViewModes) {
if (bmhd.w>LOWIDTH) picmap->ViewModes=HIRES;
if (bmhd.h>LOHEIGHT) picmap->ViewModes|=LACE;
}
/* Read planes into RAM for ease of decompression */
if (Mode==RAM_MODE) sourcebuf=bufstart=pdiskptr; /* memory-resident IFF? */
else { /* disk-resident IFF? */
if (!(sourcebuf=bufstart=AllocMem((long)header.ckSize,MEMF_PUBLIC)))
return(OUT_OF_MEM);
SafeRead(fp,sourcebuf,(long)header.ckSize); CloseNEW(fp);
}
InitBitMap(&picmap->BitMap,(long)bmhd.nPlanes,(long)bmhd.w,(long)bmhd.h);
/* note that we're not necessarily allocating CHIP_MEM here! */
for (i=0;i<bmhd.nPlanes;i++)
if (!(picmap->BitMap.Planes[i]=AllocMem(RASSIZE(bmhd.w,bmhd.h),MEMF_PUBLIC))) {
FreeBitMap(&picmap->BitMap);
FreeMem(bufstart,(long)header.ckSize);
return(OUT_OF_MEM);
}
i=Expand(&bmhd,bufstart,&picmap->BitMap);
if (Mode==DISK_MODE) FreeMem(bufstart,(long)header.ckSize);
return(i); /* error if unpacking prob */
}
void FreeBitMap(struct BitMap *bitmap)
{
short i;
/* take into acct partially allocated maps (due to error) */
for (i=0;i<bitmap->Depth;i++) {
if (bitmap->Planes[i]) FreeMem(
bitmap->Planes[i],bitmap->BytesPerRow*bitmap->Rows);
}
memset(bitmap,0,sizeof(bitmap)); /* prevent dbl-dealloc errs */
}
/* Fast line decompress/deinterleave : NEW VERSION */
Expand(BitMapHeader *bmhd,register unsigned char *sourcebuf,struct BitMap *bitmap)
{
register char n,*destbuf; /* in order of preferred allocation */
register short plane,rowlen,rowbytes,i;
short planes=bmhd->nPlanes,maskplane = -1;
/* This routine now supports mask (stencil) planes and brushes. The only
thing it doesn't support is "trimming" the right edge of brushes to
the background color if they're not exactly modulo 16 wide. DPaint III
doesn't bother either, if you try to load a brush as a screen. */
rowlen=((bmhd->w +15) & 0xFFF0) >> 3; /* round widths up to word boundary */
/* For deinterleaving purposes, decompress (but don't store)
any mask planes (if present). */
if (bmhd->masking==mskHasMask) {
maskplane=planes;
planes++;
}
for (i=0;i<bmhd->h;i++) /* process n lines/screen */
for (plane=0;plane<planes;plane++) { /* process n planes/line */
if (plane!=maskplane) destbuf=(char *)(bitmap->Planes[plane])+rowlen*i;
if (bmhd->compression==cmpByteRun1) { /* compressed screen? */
rowbytes=rowlen;
while (rowbytes>0) { /* unpack until 1 scan-line complete */
n=*sourcebuf++; /* fetch block run marker */
/* uncompressed block? copy n bytes verbatim */
if (n>=0) {
++n;
if (plane!=maskplane) {
movmem(sourcebuf,destbuf,(unsigned int)n);
destbuf+=n;
}
rowbytes-=n; sourcebuf+=n;
}
else { /* compressed block? expand n duplicate bytes */
n=-n+1;
if (plane!=maskplane) {
memset(destbuf,(int)(*sourcebuf),(int)n);
destbuf+=n;
}
rowbytes -=n; sourcebuf++;
}
} /* finish unpacking line */
if (rowbytes) return(EXPAND_ERR); /* shouldn't be any left over! */
}
else { /* uncompressed? just copy */
if (plane!=maskplane) {
movmem(sourcebuf,destbuf,(unsigned int)rowlen);
destbuf+=rowlen;
}
sourcebuf+=rowlen;
}
} /* finish interleaved planes, lines */
return(0); /* good result! */
}